Events are an important part of component-based programming. An event is a component-issued notification that something of interest has occurred. For example, a program developer may use one, type of event to specify how the program should behave when the left mouse button is pressed while the mouse cursor is over a particular icon. The component issuing the event is known as an event source, while a component that receives the event is called an event listener. An object known as an event handler governs the particular behavior triggered by the event.
In the VISUAL BASIC® development system, commercially available from Microsoft Corp. of Redmond, Wash., a component can declare an event using the Event keyword and raise it using the RaiseEvent keyword, as illustrated by the following example:
Event MyEvent (ByVal i As Integer)Sub MyMethod( )RaiseEvent MyEvent(123)End SubAn event can be handled by declaring a field with a WithEvents modifier, initializing the field, and providing an event handler whose name is specially named. In the following example, a composite class handles events for two instances of the MyComponent class.
Public WithEvents a As MyComponentPublic WithEvents b As MyComponentPrivate Sub a_MyEvent(ByVal i As Integer)MsgBox “a raised MyEvent with param” & CStr(i)End SubPrivate Sub b_MyEvent(ByVal i As Integer)MsgBox “b raised MyEvent with param” & CStr(i)End SubPrivate Sub Class_Initialize( )Set a = New MyComponentSet b = New MyComponentEnd Sub
Event support in the VISUAL BASIC® development system is based on an event infrastructure provided by Object Linking and Embedding (OLE) and OLE Automation, which define certain interfaces that enable the management of events. These interfaces allow one component to handle events for a different component. In this system, events are implemented using interfaces. A component indicates what events it raises by publishing information about one or more source interfaces. A component handles events for an event source by implementing one or more of these source interfaces and indicating its interest in events on a per-interface basis.
While the Java language itself does not specifically support events, the JavaBeans standard uses an interface-based event model similar to that used in OLE and OLE Automation. This model differs from the OLE/OLE Automation model, however, in the ways in which connections are managed. The OLE/OLE Automation model uses connection point interfaces to manage relationships between event sources and event listeners, while the JavaBeans model uses interfaces known as design patterns. In the JavaBeans model, to enable connection of event handlers, an event source supplies an AddXxxListener method that takes a parameter of interface type XxxListener.
Interfaces are essentially groupings of events, such as mouse-related events. These groupings are arbitrary and static, i.e., fixed at the time of development. In development systems in which interfaces are used for event handling, the developer is not able to manipulate event handlers on an individual basis. For example, even if the developer is only interested in using a mouse button click event, the developer must still write event handlers for the other events in the interface in which the mouse button click event is packaged.
Typically event handlers are sparse; most components have at least one handled event, but most events are unhandled. This mismatch between mechanism and usage results in additional overhead in a number of dimensions. For example, when many events appear in a single interface, the additional overhead includes unnecessary size and performance costs. In the worst case scenario, a component must provide many actual event handlers when only one event handler actually does anything useful.
JavaBeans allows a developer to use multiple interfaces. Unfortunately, using interfaces to provide finer granularity does not alleviate this problem. Instead of a single interface with N events, a component could provide N interfaces, each with a single event. Such a system would result in one interface per event and one class per handled event. Because the number of components is large, the number of events is large, as is the number of event handlers. As a result, considerable storage resources, both on disk and in memory, may be consumed.
Another drawback of interface-based event systems is that they do not support true pluggability. To connect two components, the source of the events must be provided with an implementation of an event interface. However, even if a component implements a method that is “plug compatible” with an event from another component, it is not possible to wire the method and the event together directly. The sink component would have to implement the event interface required by the source component, a rather unlikely scenario. To complete the wiring of two components, “glue code” must be provided. Pluggability could be a significant building block in the construction of high-level development tools and/or end-user focused development tools that allow pre-built components to be wired together without the need for generation and compilation of “glue” source code.
Another drawback is that conventional interface-based event systems do not provide automatic support for multicasting of events. Because neither standard nor default multicast behavior is provided, components' support for multicasting of events varies arbitrarily. Some components support multicast, but others do not. Among those components that do support multicast, some multicast in the order in which event handlers were connected, others do the opposite, and still others multicast in other ways.
Further, existing interface-based event systems are brittle with respect to versioning. Arguments are typically specified in an “unpacked” format that essentially hardwires the source and listener together. Because the declaration of an event handler specifically names the arguments of the event, it is difficult, if not impossible, for an event source to change the behavior of the event, e.g., by supplying an additional parameter, without breaking existing clients.